<?php

abstract class JACL
{
    /** @var Zend_Acl */
    protected static $acl;

    /**
     * @return void
     */
    protected static function buildAclRoles()
    {
        if (!isset(self::$acl)) {
            return;
        }

        self::$acl->addRole('0'); // For Guest

        $userTypePOJOs = Application_Model_UserType::getUserTypes(true);
        $length = count($userTypePOJOs);
        if ($length > 0) {
            $processing = array();

            self::$acl->addRole((string)$userTypePOJOs[0]->ID);
            array_push($processing, array_shift($userTypePOJOs));
            while (($processed = array_shift($processing)) !== null) {
                /** @var UserTypePOJO $processed */
                foreach ($userTypePOJOs as $key => $userTypePOJO) {
                    if ($processed->Level != $userTypePOJO->Level - 1) {
                        continue;
                    }

                    if ($processed->Lft >= $userTypePOJO->Lft ||
                        $processed->Rgt <= $userTypePOJO->Rgt
                    ) {
                        continue;
                    }

                    self::$acl->addRole((string)$userTypePOJO->ID, (string)$processed->ID);
                    array_push($processing, $userTypePOJO);
                    unset($userTypePOJOs[$key]);
                }

                $userTypePOJOs = array_values($userTypePOJOs);
            }

//            self::$acl->addRole((string)$userTypePOJOs[0]->ID);
//            for ($i = 1; $i < $length; $i++) {
//                $count = 1;
//                while ($userTypePOJOs[$i]->Level != $userTypePOJOs[$i - $count]->Level + 1) {
//                    $count++;
//                }
//
//                $child = $userTypePOJOs[$i]->ID;
//                $parent = $userTypePOJOs[$i - $count]->ID;
//                self::$acl->addRole((string)$child, (string)$parent);
//            }
        }
    }

    /**
     * @return void
     */
    protected static function setPermissions()
    {
        if (!isset(self::$acl)) {
            return;
        }

        $assetPOJO = Application_Model_Asset::getRootAsset();
        foreach ($assetPOJO->Rules as $rule) {
            $resource = $rule->Name;
            self::$acl->addResource($resource);
            foreach ($rule->Permissions as $key => $value) {
                if ($value == 0) {
                    self::$acl->deny((string)$key, $resource);
                } elseif ($value == 1) {
                    self::$acl->allow((string)$key, $resource);
                }
            }
        }
    }

    /**
     * @return Zend_Acl
     */
    public static function factory()
    {
        if (!isset(self::$acl)) {
            self::$acl = new Zend_Acl();
            self::buildAclRoles();
            self::setPermissions();
        }

        return self::$acl;
    }
}
